local AddOnName, Env = ...; local ADDON, DEV = Env[1], Env[1].DEV
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local AceConfigRegistry	= LibStub("AceConfigRegistry-3.0")
local DiesalStyle 		= LibStub("DiesalStyle-1.0")
local DiesalGUI 			= LibStub("DiesalGUI-1.0")
local DiesalMenu 			= LibStub('DiesalMenu-1.0')
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local pairs, ipairs							= pairs,ipairs
local type	 									= type
local gsub, sub, find, format 			= string.gsub, string.sub, string.find, string.format
local concat									= table.concat
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| RotationSelecter |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADDON.RotationConfigs = {}
ADDON.Rotations = {}
for i = 1, 6 do ADDON.Rotations[i] = {} end
-- ~~| RotationSelecter StyleSheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

local windowStyleSheet = {	
	['content-background'] = {
		type			= 'texture',			
		color			= '1f1f1f',
	},	
}
local autoButtonStyleSheet = {
	['frame-background'] = {
		type			= 'texture',
		layer			= 'BACKGROUND',			
		color			= '000000',
		offset		= 0,
	},	
	['frame-gradient'] = {
		type			= 'texture',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',
		color			= 'ffffff',
		alpha 		= .06,
		alphaEnd		= .12,
		offset		= {-1,-1,-1,-8},
	},
	['frame-inline'] = {
		type			= 'outline',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',
		color			= 'ffffff',
		alpha			= .03,		
		alphaEnd		= .09,
		offset		= -1,
	},
	['frame-highlight'] = {
		type			= 'texture',
		layer			= 'HIGHLIGHT',		
		color			= 'ffffff',
		alpha			= .09,
		offset		= -1,
	},
	['text-Font'] = {			
		type			= 'font',		
		color			= '00cb00',		
	},			
}
local manualButtonStyleSheet = {
	['frame-background'] = {
		type			= 'texture',
		layer			= 'BACKGROUND',			
		color			= '000000',
		offset		= 0,
	},	
	['frame-gradient'] = {
		type			= 'texture',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',
		color			= 'ffffff',
		alpha 		= .06,
		alphaEnd		= .12,
		offset		= {-1,-1,-1,-8},
	},
	['frame-inline'] = {
		type			= 'outline',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',
		color			= 'ffffff',
		alpha			= .03,		
		alphaEnd		= .09,
		offset		= -1,
	},
	['frame-highlight'] = {
		type			= 'texture',
		layer			= 'HIGHLIGHT',		
		color			= 'ffffff',
		alpha			= .09,
		offset		= -1,
	},
	['text-Font'] = {			
		type			= 'font',		
		color			= 'cc8800',		
	},			
}
local dropdownStyleSheet = {	
	['frame-buttonbackground'] = {			
		type			= 'texture',
		layer			= 'BACKGROUND',
		gradient		= 'VERTICAL',							
		color			= '000000',		
		offset		= 0,		
	},
	['frame-highlight'] = {			
		type			= 'texture',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',							
		color			= 'ffffff',			
		alpha 		= .15,
		alphaEnd		= .25,
		offset		= -1,		
	},
	['frame-inline'] = {		
		type			= 'outline',
		layer			= 'BORDER',
		gradient		= 'VERTICAL',	
		color			= 'ffffff',
		alpha 		= .03,
		alphaEnd		= .07,
		offset		= -1,	
	},		
	['frame-hover'] = {		
		type			= 'outline',
		layer			= 'HIGHLIGHT',	
		color			= '00a8ff',
		alpha			= .3,
		offset		= -1,		
	},
	['frame-arrow'] = {			
		type			= 'texture',
		layer			= 'BORDER',								
		texFile		= 'DiesalGUIcons',
		texCoord		= {2,1,16,256,128},				
		alpha 		= .7,		
		offset		= {nil,-4,-6,nil},
		height		= 5,
		width			= 6,				
	},	
	['text-color'] = {
		type			= 'Font',
		color			= 'cccccc',
	},
	['dropdown-background'] = {				
		type			= 'texture',
		layer			= 'BACKGROUND',
		color			= '000000',			
	},	
	['dropdown-inline'] = {	
		type			= 'outline',
		layer			= 'BORDER',
		color			= 'ffffff',
		gradient		= 'VERTICAL',
		alpha 		= .03,
		alphaEnd 	= .1,
		offset		= -1,				
	},
	['dropdown-highlight'] = {
		type			= 'texture',
		layer			= 'BORDER',
		color			= 'ffffff',
		gradient		= 'VERTICAL',
		alpha 		= .02,
		alphaEnd		= .07,
		offset		= -1,
		height		= 10,
	},
	['dropdown-shadow'] = {			
		type			= 'shadow',		
	},	
}	
local configButtonStyle = {
	type			= 'texture',
	texFile		='DiesalGUIcons',
	texCoord		= {2,5,16,256,128},
	alpha 		= .5,	
	offset		= 0,			
}
local configButtonNormal = {
	type			= 'texture',	
	alpha 		= .5,			
}
local configButtonOver = {
	type			= 'texture',	
	alpha 		= 1,		
} 
-- ~~| RotationSelecter Colors |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GREY75		= ADDON:GetTxtColor('c0c0c0')
local GREY50		= ADDON:GetTxtColor('808080')
local BLUE			= ADDON:GetTxtColor('0099e6')	
local ORANGE		= ADDON:GetTxtColor('e6c000') 
local PURPLE		= ADDON:GetTxtColor('9900e5') 
local RED			= ADDON:GetTxtColor('ff0000') 
local YELLOW		= ADDON:GetTxtColor('ffff00')

local function getName(s)	
	local name, author = s:match("^%s*(.*)%((.*)%)%.lua$")	
	return ADDON:TrimString(name), ADDON:TrimString(author)	
end
-- ~~| RotationSelecter Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {		
	['Update'] = function(self)		
		-- ~~ Update Position ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		self.frame:ClearAllPoints()
		if self.db.top and self.db.left then
			self.frame:SetPoint("TOP",UIParent,"BOTTOM",0,self.db.top)
			self.frame:SetPoint("LEFT",UIParent,"LEFT",self.db.left,0)
		else
			self.frame:SetPoint("CENTER",UIParent,"CENTER")
		end	
		
		self:LoadRotations()	
		self.frame[self.db.show and "Show" or "Hide"](self.frame)				
	end,
	['OnFireHack'] = function(self)
		self:LoadRotations()		
	end,	
	['LoadRotations'] = function(self)
		if not FireHack then return end		
			
		for i = 1, 6 do 
			if self.db[ADDON.PLAYERCLASS]['rotation'..i..'filename'] then				
				if self:LoadRotation(i,self.db[ADDON.PLAYERCLASS]['rotation'..i..'filename'],self.db[ADDON.PLAYERCLASS]['rotation'..i..'name']) then
					self['selecter'..i]:SetText(self.db[ADDON.PLAYERCLASS]['rotation'..i..'name'])					
				end
			else
				self:RemoveRotation(i)
			end			
		end		
	end,	
	['LoadRotation'] = function(self,rotationNumber,filename,name,author,dontUpdateConfigs)				
		local file				
		
		if rotationNumber < 6 then -- Rotation
			ADDON.Engine:StopRotationEngine()		
			file = ReadFile(GetLoaderFolder()..ADDON.SCRIPTPATH..ADDON.PLAYERCLASS.."\\"..filename)
		else -- Interrupt	
			ADDON.Engine:StopInterruptEngine()	
			file = ReadFile(GetLoaderFolder()..ADDON.SCRIPTPATH.."INTERRUPT\\"..filename)
		end		
		if not file then 			
			ADDON:Error("|cffffff00'"..filename.."'|cffff0000 no longer exists.")				
			self:RemoveRotation(rotationNumber)			
		return end
		
		local func,err = loadstring(file,filename)	
		if err then			
			local line, err = string.match(err,"^%[string.-%]:(%d-):(.*)$")				
			ADDON:Error("|cffffff00'"..filename.."' |cffff0000 Line |cffffff00'"..line.."' |r"..err)		
			self:RemoveRotation(rotationNumber)
		return end
		
		local data, rotation = func(ADDON.API)
		if type(data) ~= 'table' then 			
			ADDON:Error("|cffffff00'"..filename.."' |cffff0000 Data table is invalid.")	
			self:RemoveRotation(rotationNumber)
		elseif type(rotation) ~= 'function' then
			ADDON:Error("|cffffff00'"..filename.."' |cffff0000 Rotation function is invalid.")			
			self:RemoveRotation(rotationNumber)
		else -- OK		
			self.db[ADDON.PLAYERCLASS]['rotation'..rotationNumber..'filename'] = filename
			self.db[ADDON.PLAYERCLASS]['rotation'..rotationNumber..'name'] = name			
			data.name, data.author = getName(filename)	
			ADDON.Rotations[rotationNumber].data = data
			ADDON.Rotations[rotationNumber].rotation = rotation
			if data.config then				
				data.config.author = data.author
				self:LoadConfig(data.config,rotationNumber)
				
				self['configButton'..rotationNumber]:Show()	
			else	
				self['configButton'..rotationNumber]:Hide()		
			end
			self:UpdateConfigs()							
			return true
		end							
	end,
	['LoadConfig'] = function(self,configTable,rotationNumber)	
		if not configTable then return end	-- JIC	
		-- ~~ set option IDs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		for s = 1, #configTable do
			for o = 1, #configTable[s] do
				local option = configTable[s][o]
				if option.name then option.id = format( '%s_%s_%s_%s',ADDON:CreateID(configTable.id),ADDON:CreateID(configTable[s].section),option.type,ADDON:CreateID(option.name) )	end
			end					
		end
		-- ~~ setup new DB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		
		if not self.db.configs[configTable.id] then
			self.db.configs[configTable.id] = {
				currentSet 		= 1,
				id 				= configTable.id,
				sets 				= {},
				sections			= {},
			}			
		end
		-- ~~ Update DB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		local configDB = self.db.configs[configTable.id]			
		for set = 1, 9 do	-- NUMBER OF SETS
			-- setup new set entry
			if not configDB.sets[set] then
				configDB.sets[set] = {
					name	= "set"..set,
					id 	= configTable.id,
				}
			end
			-- update options
			for s = 1, #configTable do
				-- setup section states				
				for o = 1, #configTable[s] do				
					if configTable[s][o].name then
						local optionTable = configTable[s][o]
						if not configDB.sets[set][optionTable.id] then
							-- setup new option entry
							if optionTable.type:lower() == 'hotkey' then
								if not optionTable.value then optionTable.value = {} end
								optionTable.value.strict = optionTable.strict or false
							end
							configDB.sets[set][optionTable.id] = {
								id			= optionTable.id,
								enable	= optionTable.enable,
								value		= optionTable.value,
								type		= optionTable.type,
							}
						else
							-- update option entry
							local optionDB = configDB.sets[set][optionTable.id]
							if optionDB.type ~= optionTable.type then
							if optionTable.type:lower() == 'hotkey' and optionDB.value.strict ~= nil then
								optionTable.value.strict = optionTable.strict or false
							end	
								optionDB.type	= optionTable.type
								optionDB.value	= optionTable.value
							end
						end
					end
				end
			end
		end	
		-- ~~ Add Rotation Config ~~~~~~~~~~~~~~~~~~~~~~~~~~~		
		if not ADDON.RotationConfigs[configTable.id] then
			ADDON.RotationConfigs[configTable.id]	= ADDON:NewRotationConfig()
		-- ~~ Add Config Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~										
			if not ADDON.MenuData.rotationConfigs then 
				 ADDON.MenuData.rotationConfigs = {
				 	name = '|cff00aaffRotation Configs',
					order = 30,
					menuData = {},				
				}	
			end
			ADDON.MenuData.rotationConfigs.menuData[configTable.id] = {
				order = rotationNumber,
				name = configTable.name,
				onClick = function()
					local frame = ADDON.RotationConfigs[configTable.id].frame 
					frame[frame:IsVisible() and "Hide" or "Show"](frame)
					configDB.show = frame:IsVisible()					
					AceConfigRegistry:NotifyChange(AddOnName)
				end,
				check	= function()
					return configDB.show
				end,					
			}									
		end
		-- ~~ Update Rotation Config ~~~~~~~~~~~~~~~~~~~~~~~~					
		ADDON.RotationConfigs[configTable.id]:SetSettings(configTable,configDB)									
	end,	
	['RemoveRotation'] = function(self,rotationNumber)					
		ADDON.Engine:StopRotationEngine() 		
		
		self['selecter'..rotationNumber]:Reset()
		self['configButton'..rotationNumber]:Hide()		
		self.db[ADDON.PLAYERCLASS]['rotation'..rotationNumber..'filename'] = nil
		self.db[ADDON.PLAYERCLASS]['rotation'..rotationNumber..'name'] = nil		
		wipe(ADDON.Rotations[rotationNumber])			
		self:UpdateConfigs()							
	end,
	['UpdateConfigs'] = function(self)
		for id, rc in pairs(ADDON.RotationConfigs) do
			local found 
			for r = 1, #ADDON.Rotations do
				if ADDON.Rotations[r].data and ADDON.Rotations[r].data.config then 
					if ADDON.Rotations[r].data.config.id == id then found = true break end
				end			
			end
			if not found then
				-- remove config				
				ADDON:ReleaseRotationConfig(rc)
				ADDON.RotationConfigs[id] = nil
				-- remove menuItem
				ADDON.MenuData.rotationConfigs.menuData[id] = nil
				if not next(ADDON.MenuData.rotationConfigs.menuData) then
					ADDON.MenuData.rotationConfigs = nil
				end						
			end
		end
	end,		
	['Show'] = function(self)
		self.frame:Show()
	end,
	['Hide'] = function(self)
		self.frame:Hide()
	end,
}
-- ~~| RotationSelecter Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ADDON:constructRotationSelecter()
	local self = {}
	self.db = ADDON.db.profile.rotationSelecter
	-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	local settings = {
		configs 			= {},
		rows 				= {},
		configList 		= {},
		setList			= {},
		orderedSetList	= {},
	}
	settings = settings
	-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	local window = DiesalGUI:Create('Window')
	-- window:ReleaseTextures()
	window:AddStyleSheet(windowStyleSheet)
	window:SetSettings({
		top				= self.db.top,
		left				= self.db.left,			
		height	 		= 147,
		width				= 346,		
		sizerR			= false,
		sizerB			= false,
		sizerBR			= false,
	},true)
	window:SetTitle(RED..AddOnName,GREY75..'Rotation Selecter')	
	window:SetEventListener('OnDragStop', function(this,event,left,top)
		self.db.left 	= left
		self.db.top 	= top
	end)
	window:SetEventListener('OnClose', function(this,event)
		self.db.show = false
		AceConfigRegistry:NotifyChange(AddOnName)
	end)	
 
	for i = 1 , 6 do	
	 	local text = window.content:CreateFontString(nil,"OVERLAY",'DiesalFontNormal')	 	
	 	text:SetPoint("TOPLEFT",4, (i*-20)+10)
		text:SetSize(16,16)
		text:SetJustifyH("LEFT")
		text:SetAlpha(.5)
		text:SetJustifyV("TOP")
		text:SetWordWrap(false)
		text:SetText(i==6 and 'I' or i)
	 	self['selecter'..i..'Text'] = text
	 	
	 	local selecter = DiesalGUI:Create('ComboBox')	
		selecter:SetParent(window.content)
		selecter:SetPoint('TOPLEFT',16, (i*-20)+14)
		selecter:SetWidth(200)			
		selecter:SetEventListener('OnButtonEnter', function(this)
			-- if not ADDON.Configurator.db.tooltips then return end
			GameTooltip:SetOwner(selecter.frame, "ANCHOR_TOPRIGHT",0,2)
			GameTooltip:AddLine(format('%sRotation Selecter',BLUE))
			GameTooltip:AddLine(' ')
			GameTooltip:AddLine(format('%sSelect a rotation to load into this slot for your class.',GREY75),nil,nil,nil,1)	
			GameTooltip:Show()
		end)
		selecter:SetEventListener('OnButtonLeave', function(this)
			GameTooltip:Hide()
		end)
		selecter:SetEventListener('OnValueSelected', function(this,event,key,value)		
			if key == 'none' then -- 
				self:RemoveRotation(i)											
			return end			
			self:LoadRotation(i,key,value)			
		end)	
		selecter:SetEventListener('OnButtonClick', function(this)
			if not FireHack then return end
			local values = {['none'] = ''}
			local name, author, files			
			
			if i < 6 then -- Rotation folder		
				files = GetFilesInDirectory(GetLoaderFolder()..ADDON.SCRIPTPATH..ADDON.PLAYERCLASS.."\\*lua")
			else -- Interrupt Folder
				files = GetFilesInDirectory(GetLoaderFolder()..ADDON.SCRIPTPATH.."INTERRUPT\\*lua")
			end
			 
			if files[1] ~= '' then			
				for i = 1, #files do						
					name, author = getName(files[i])			
					if name and name ~='' and author and author ~='' then						  		
						values[files[i]] = format('%s |cff00aaff%s', name, author)						
					else
						ADDON:Debug('dev',"Invalid filename: "..files[i]..". Use: profilename followed by the author in brackets, ie. 'Frost PVP (Dzl)'")							
					end	
				end			
			end		
			
			selecter:SetList(values)
		end)
		selecter.editBox:EnableMouse(false)
		selecter.editBox:SetJustifyH("LEFT")
		selecter.editBox:SetTextInsets(3,2,2,0)
	 	self['selecter'..i] = selecter
		local overlay = CreateFrame('Button',nil,selecter.editBox)
		overlay:SetAllPoints()
		overlay:EnableMouse()
		overlay:SetScript('OnEnter', 	function()
			local data = ADDON.Rotations[i].data	
			if data then	
				GameTooltip:SetOwner(overlay, "ANCHOR_TOPLEFT",0,2)				
				GameTooltip:AddDoubleLine(GREY75..data.name..'|r '..data.author,data.version and 'V'..data.version or '', 0, .66, 1, 1, 1,0)				
				GameTooltip:AddLine(' ')	
				if data.desc then 									
					GameTooltip:AddLine(data.desc,.8,.8,.8,1)
					GameTooltip:AddLine(' ')		
				end
				GameTooltip:AddDoubleLine(format('%sLeft  Click:',BLUE),format('%sReload Rotation',YELLOW))				
				GameTooltip:Show()
			end	
		end)
		overlay:SetScript('OnLeave', 	function()		
			GameTooltip:Hide()
		end)
		overlay:SetScript('OnClick', 	function(this,button)					
			if button == 'LeftButton' then
				if self.db[ADDON.PLAYERCLASS]['rotation'..i..'filename'] and self.db[ADDON.PLAYERCLASS]['rotation'..i..'name'] then 
					self:LoadRotation(i,self.db[ADDON.PLAYERCLASS]['rotation'..i..'filename'],self.db[ADDON.PLAYERCLASS]['rotation'..i..'name'])
				end		
			end	
		end)	
		
		local configButton = DiesalGUI:Create('Button')
		configButton:SetStyle('frame',configButtonStyle)				
		configButton:SetSettings({		
			width			= 16,		
			height		= 16,
		},true)			
		configButton:SetParent(window.content)
		configButton:SetPoint('TOPLEFT',selecter.button,'TOPRIGHT',0,0)		
		configButton:SetEventListener('OnEnter', 	function()			
			-- if not ADDON.Configurator.db.tooltips then return end
			GameTooltip:SetOwner(configButton.frame, "ANCHOR_TOPRIGHT",0,2)				
			GameTooltip:AddLine(format('%sOpen Rotation Configuration',BLUE))				
			GameTooltip:Show()
			configButton:SetStyle('frame',configButtonOver)			
		end)
		configButton:SetEventListener('OnLeave', 	function()			
			GameTooltip:Hide()
			configButton:SetStyle('frame',configButtonNormal)
		end)		
		configButton:SetEventListener('OnClick', 	function(this,event)
			ADDON.RotationConfigs[ADDON.Rotations[i].data.config.id].settings.db.show = true					
			ADDON.RotationConfigs[ADDON.Rotations[i].data.config.id]:Show()								
		end)
		configButton:Hide()
		self['configButton'..i] = configButton		
		
		local HKAutoButton = DiesalGUI:Create('Button','HKAutoButton'..i)
		HKAutoButton:AddStyleSheet(autoButtonStyleSheet)		
		HKAutoButton:SetParent(window.content)
		HKAutoButton:SetPoint('TOPLEFT',selecter.button,'TOPRIGHT',16,0)
		HKAutoButton:RegisterForClicks("AnyUp", "AnyDown")	
		HKAutoButton:SetSettings({
			width			= 50,
			height		= 16,
		},true)	
		HKAutoButton:SetEventListener('OnEnter', 	function()			
			-- if not ADDON.Configurator.db.tooltips then return end
			GameTooltip:SetOwner(HKAutoButton.frame, "ANCHOR_TOPRIGHT",0,2)				
			GameTooltip:AddLine(format('%sAuto Rotation Hotkey',BLUE))			
			GameTooltip:AddLine(' ')
			GameTooltip:AddLine(format('%sThis hotkey will toggle the selected Rotation on or off.',GREY75),nil,nil,nil,1)	
			GameTooltip:AddLine(' ')					
			GameTooltip:AddDoubleLine(format('%sRight  Click:',BLUE),format('%sChange Key Binding',YELLOW))
			GameTooltip:Show()			
		end)
		HKAutoButton:SetEventListener('OnLeave', 	function()			
			GameTooltip:Hide()
		end)		
		HKAutoButton:SetEventListener('OnClick', 	function(this,event,button,down)					
				if button == 'RightButton' and not down then
					self.bindButton = 'HKAutoButton'..i 
					self.bindOverlay:Show()
					self.bindDialogue:Show()					
				elseif button == 'LeftButton' and down then 
					ADDON.Engine:InputHandler(i,'auto') 
				end				
			end)
		self['HKAutoButton'..i] = HKAutoButton		
		
		if i < 6 then 	
			local HKManualButton = DiesalGUI:Create('Button','HKManualButton'..i)
			HKManualButton:AddStyleSheet(manualButtonStyleSheet)
			HKManualButton:SetParent(window.content)
			HKManualButton:SetPoint('TOPRIGHT',-6,(i*-20)+14)	
			HKManualButton:RegisterForClicks("AnyUp", "AnyDown")		
			HKManualButton:SetSettings({
				width			= 50,
				height		= 16,
			},true)	
			HKManualButton:SetEventListener('OnEnter', 	function()			
				-- if not ADDON.Configurator.db.tooltips then return end
				GameTooltip:SetOwner(HKManualButton.frame, "ANCHOR_TOPRIGHT",0,2)				
				GameTooltip:AddLine(format('%sManual Rotation Hotkey',BLUE))			
				GameTooltip:AddLine(' ')
				GameTooltip:AddLine(format('%sThis hotkey will run the selected rotation while it is pressed.',GREY75),nil,nil,nil,1)	
				GameTooltip:AddLine(' ')					
				GameTooltip:AddDoubleLine(format('%sRight  Click:',BLUE),format('%sChange Key Binding',YELLOW))
				GameTooltip:Show()			
			end)
			HKManualButton:SetEventListener('OnLeave', 	function()			
				GameTooltip:Hide()
			end)	
			HKManualButton:SetEventListener('OnClick', 	function(this,event,button,down)				
				if button == 'RightButton' and not down then
					self.bindButton = 'HKManualButton'..i 
					self.bindOverlay:Show()
					self.bindDialogue:Show()
				elseif button == 'LeftButton' then
					ADDON.Engine:InputHandler(i,'manual',down) 					
				end				
			end)
			self['HKManualButton'..i] = HKManualButton
		end	
	end
	
	-- Interrupt selecter changes
	self.selecter6:SetEventListener('OnButtonEnter', function(this)
		-- if not ADDON.Configurator.db.tooltips then return end
		GameTooltip:SetOwner(self.selecter6.frame, "ANCHOR_TOPRIGHT",0,2)
		GameTooltip:AddLine(format('%sInterrupt Selecter',BLUE))
		GameTooltip:AddLine(' ')
		GameTooltip:AddLine(format('%sSelect an Interrupt rotation to load into this slot.',GREY75),nil,nil,nil,1)	
		GameTooltip:Show()
	end)
	self.HKAutoButton6:SetEventListener('OnEnter', 	function()			
		-- if not ADDON.Configurator.db.tooltips then return end
		GameTooltip:SetOwner(self.HKAutoButton6.frame, "ANCHOR_TOPRIGHT",0,2)				
		GameTooltip:AddLine(format('%sAuto Interrupt Hotkey',BLUE))			
		GameTooltip:AddLine(' ')
		GameTooltip:AddLine(format('%sThis hotkey will toggle the Interrupt Rotation on or off.',GREY75),nil,nil,nil,1)	
		GameTooltip:AddLine(' ')					
		GameTooltip:AddDoubleLine(format('%sRight  Click:',BLUE),format('%sChange Key Binding',YELLOW))
		GameTooltip:Show()			
	end)	
	-- Binding frame	
	local bindDialogue = DiesalGUI:Create('Window')
	bindDialogue:SetSettings({				
		height	 		= 100,
		width				= 200,		
		sizerR			= false,
		sizerB			= false,
		sizerBR			= false,
	},true)
	bindDialogue:SetTitle(YELLOW..'    Set Button Hotkey')	
	bindDialogue.frame:EnableMouse(false) 
	bindDialogue.titleBar:EnableMouse(false) 
	bindDialogue.closeButton:Hide()	
	bindDialogue.titletext:SetJustifyH("CENTER")	
	bindDialogue.frame:SetFrameStrata('TOOLTIP')
	bindDialogue.frame:SetFrameLevel(99)
	local bindDialogueText = bindDialogue.content:CreateFontString(nil,"OVERLAY",'DiesalFontNormal')	 	
 	bindDialogueText:SetPoint("TOPLEFT",5,-6)
 	bindDialogueText:SetPoint("BOTTOMRIGHT",-5,6)	
	bindDialogueText:SetJustifyH("LEFT")
	bindDialogueText:SetJustifyV("CENTER")
	bindDialogueText:SetWordWrap(true)
	bindDialogueText:SetText(GREY75..'Press any key to bind it to the button, escape to cancel or backspace to remove the current binding.')	
	bindDialogue:Hide()
	
	local bindOverlay = CreateFrame('Frame',nil,UIParent)
	bindOverlay:SetAllPoints(UIParent)
	bindOverlay:SetFrameStrata('TOOLTIP')
	bindOverlay:SetFrameLevel(90)	
	bindOverlay:EnableMouse(true)
	bindOverlay:EnableKeyboard(true)
	bindOverlay.texture = bindOverlay:CreateTexture()
	bindOverlay.texture:SetAllPoints(bindOverlay)
	bindOverlay.texture:SetTexture(0,0,0,.3)
	bindOverlay:Hide()	
	bindOverlay:SetScript("OnKeyUp", function(this, key)		
		if key == "ESCAPE" then 
			bindOverlay:Hide()
			bindDialogue:Hide()
			return
		elseif key == "BACKSPACE" then -- clear Bindings			
			local bindings = {GetBindingKey("CLICK "..self.bindButton..":Button4")}
			for i = 1, #bindings do 
				SetBinding(bindings[i])
			end
			SaveBindings(GetCurrentBindingSet())
			bindOverlay:Hide()
			bindDialogue:Hide()
			return
		elseif key == "LSHIFT" or key == "RSHIFT" or key == "LCTRL" or key == "RCTRL" or key == "LALT" 	or key == "RALT" 	or key == "UNKNOWN" then			
			return
		end
		
		local alt = IsAltKeyDown() and "ALT-" or ""
		local ctrl = IsControlKeyDown() and "CTRL-" or ""
		local shift = IsShiftKeyDown() and "SHIFT-" or ""		
		-- clear current Bindings
		local bindings = {GetBindingKey("CLICK "..self.bindButton..":LeftButton")}
		for i = 1, #bindings do 
			SetBinding(bindings[i])
		end
		-- set New Binding 
		SetBindingClick(alt..ctrl..shift..key,self.bindButton, 'LeftButton')		
		-- save New Bindingd
		SaveBindings(GetCurrentBindingSet())
		bindOverlay:Hide()
		bindDialogue:Hide()
	end)
	
	-- ~~ Frames ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self.window 				= window
	self.frame 					= window.frame
	self.bindOverlay 			= bindOverlay
	self.bindDialogue 		= bindDialogue
	-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	for method, func in pairs(methods) do
		self[method] = func
	end
	-- ~~ Style ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	-- textures = {}
	-- DiesalStyle:AddObjectStyleSheet(self,styleSheet)
	-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self:Hide()
	return self
end